﻿// ------------------------------------------------------------------------
// 项目名称：Canroc.Net 
// 版权归属：Canroc（https://gitee.com/canroc）
//
// 许可证信息
// Canroc.Net项目主要遵循 Apache 许可证（版本 2.0）进行分发和使用。许可证位于源代码树根目录中的 LICENSE-APACHE 文件。
//
// 使用条款：
// 1.使用本项目应遵守相关法律法规和许可证的要求。
// 2.不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动。
// 3.任何基于本项目二次开发而产生的一切法律纠纷和责任，我们不承担任何责任
//
// 免责声明
// 对于因使用本代码而产生的任何直接、间接、偶然、特殊或后果性损害，我们不承担任何责任。
//
// 其他重要信息
// Canroc.Net 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。
// ------------------------------------------------------------------------

using Microsoft.Extensions.Configuration;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;

namespace Canroc.Net.Core.Options;

/// <summary>
///     微信支付配置项
/// </summary>
public class WeChatPayOptions : IConfigurableOptions<WeChatPayOptions>
{
    private string _certificatePassword = string.Empty;

    /// <summary>
    ///     商户号
    /// </summary>
    /// <remarks>
    ///     商户号、服务商户号
    /// </remarks>
    public string MchId { get; set; } = string.Empty;

    /// <summary>
    ///     商户API证书
    /// </summary>
    /// <remarks>
    ///     可为 证书文件路径、证书文件的Base64编码。
    /// </remarks>
    // ReSharper disable once AutoPropertyCanBeMadeGetOnly.Local
    private string Certificate { get; set; } = string.Empty;

    /// <summary>
    ///     商户API证书路径
    /// </summary>
    public string CertificatePath { get; set; } = string.Empty;

    /// <summary>
    ///     商户API证书密码
    /// </summary>
    /// <remarks>
    ///     默认为商户号
    /// </remarks>
    public string CertificatePassword
    {
        get => _certificatePassword.IsNullOrEmpty() ? MchId : _certificatePassword;
        set => _certificatePassword = value;
    }

    /// <summary>
    ///     商户API证书序列号
    /// </summary>
    public string CertificateSerialNo { get; private set; } = string.Empty;

    /// <summary>
    ///     商户API密钥
    /// </summary>
    public string ApiKey { get; set; } = string.Empty;

    /// <summary>
    ///     商户APIv3密钥
    /// </summary>
    public string ApiV3Key { get; set; } = string.Empty;

    /// <summary>
    ///     RSA公钥
    /// </summary>
    /// <remarks>
    ///     目前仅调用"企业付款到银行卡API [V2]"时使用，执行"获取RSA加密公钥API [V2]"即可获取。
    /// </remarks>
    public string RsaPublicKey { get; set; } = string.Empty;

    /// <summary>
    ///     支付通知地址
    /// </summary>
    public string PaymentNotifyUrl { get; set; } = string.Empty;

    /// <summary>
    ///     退款通知地址
    /// </summary>
    public string RefundNotifyUrl { get; set; } = string.Empty;

    /// <summary>
    ///     对账单文件路径
    /// </summary>
    public string TradeBillPath { get; set; } = string.Empty;

    /// <summary>
    ///     API证书私钥
    /// </summary>
    public RSA? RSAPrivateKey { get; private set; }

    /// <summary>
    ///     选项后期配置
    /// </summary>
    /// <param name="options"></param>
    /// <param name="configuration"></param>
    public void PostConfigure(WeChatPayOptions options, IConfiguration configuration)
    {
        if (string.IsNullOrEmpty(Certificate) || string.IsNullOrEmpty(CertificatePassword))
        {
            return;
        }

        X509Certificate2? certificate2;
        try
        {
            var path = Path.Combine(AppContext.BaseDirectory, options.CertificatePath, Certificate);
            if (File.Exists(path))
            {
                certificate2 = new X509Certificate2(path, CertificatePassword,
                    X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet |
                    X509KeyStorageFlags.Exportable);
            }
            else
            {
                throw Oops.Oh("微信支付证书未找到！");
            }
        }
        catch (CryptographicException ex)
        {
            throw Oops.Oh($"反序列化证书失败，请确认是否为微信支付签发的有效PKCS#12格式证书。原始异常信息：{ex.Message}");
        }

        options.CertificateSerialNo = certificate2.GetSerialNumberString();
        options.RSAPrivateKey ??= certificate2.GetRSAPrivateKey();
    }
}